﻿using System;
using System.Reflection;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Theming;
using System.Collections.Generic;

using SBPweb.Forge.Contracts.Events;

using SBPweb.PROvibe.Business.Shared.Contracts.Content;

namespace SBPweb.PROvibe.Business.Client.Library.Modularity
{

    public class ThemeManager
    {

        #region Private fields

        private Application app;
        private Assembly asm;
        private List<string> themeNames;

        #endregion

        #region Constructor logic

        public ThemeManager(Application app)
            : this(app, Assembly.GetCallingAssembly())
        {
        }

        public ThemeManager(Application app, Assembly asm)
        {
            this.app = app;
            this.asm = asm;
            this.themeNames = GatherThemeNames();
        }

        #endregion

        #region Property accessors

        public List<string> ThemeNames
        {
            get
            {
                return themeNames;
            }
        }

        #endregion

        #region Events

        public event EventHandler ThemeApplied;

        #endregion

        #region Methods

        public List<string> GatherThemeNames()
        {
            List<string> ret = new List<string>();
            return ret;
        }

        public void ApplyTheme(FrameworkElement frameworkElement, string themeName)
        {
            ApplyTheme(frameworkElement, GetAsmName(asm), themeName);
        }

        public void ApplyTheme(FrameworkElement frameworkElement, string assemblyName, string themeName)
        {
            ApplyTheme(frameworkElement, assemblyName, themeName, @"/{0};component/Assets/Styles.{1}.xaml");
        }

        public void ApplyTheme(FrameworkElement frameworkElement, string assemblyName, string themeName, string pathFormat)
        {
            Uri uri = new Uri(string.Format(pathFormat, assemblyName, themeName), UriKind.Relative);

            ImplicitStyleManager.SetResourceDictionaryUri(frameworkElement, uri);
            ImplicitStyleManager.SetApplyMode(frameworkElement, ImplicitStylesApplyMode.Auto);
            ImplicitStyleManager.Apply(frameworkElement);

            if (ThemeApplied != null)
            {
                ThemeApplied(frameworkElement, EventArgs.Empty);
            }
        }

        public void ApplyTheme(FrameworkElement frameworkElement, TypeDescriptor descriptor)
        {
            ModuleLoader.CreateInstance<ResourceDictionary>(descriptor, new EventHandler<ModuleLoaderObjectCreatedEventArgs<ResourceDictionary>>(s), frameworkElement);
        }

        private void s(object sender, ModuleLoaderObjectCreatedEventArgs<ResourceDictionary> e)
        {
            app.Resources.MergedDictionaries.Clear();
            app.Resources.MergedDictionaries.Add(e.Object);
            ImplicitStyleManager.ApplicationResourceDictionaryUri = e.Object.Source;
            ImplicitStyleManager.UseApplicationResources = true;
            FrameworkElement frameworkElement = e.UserState as FrameworkElement;
            ApplyTheme(frameworkElement, GetAsmName(e.Object.GetType().Assembly), string.Empty, @"/{0};component/Styles.xaml");
        }

        private string GetAsmName(Assembly asm)
        {
            return asm.FullName.Substring(0, asm.FullName.IndexOf(','));
        }

        #endregion

    }

}